package com.smartrodin.springbootrabbitmq.util;

import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期工具类
 *
 * @author back_zhang
 * @version 1.0
 */
public class DateUtils {

    private static final String DATE_PATTERN = "yyyy-MM-dd";
    private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static final String DATETIME_UNSIGNED_FORMAT = "yyyyMMddHHmmss";
    private static final String DATE_UNSIGNED_FORMAT = "yyyyMMdd";

    /**
     * 获取当前系统同日期
     *
     * @return yyyyMMddHHmmss
     */
    public static String getUnsignedDateTime() {
        DateTime dateTime = DateTime.now();
        return dateTime.toString( DATETIME_UNSIGNED_FORMAT );
    }

    /**
     * 获取当前系统日期
     *
     * @return yyyyMMdd
     */
    public static String getUnsignedDate() {
        DateTime dateTime = DateTime.now();
        return dateTime.toString( DATE_UNSIGNED_FORMAT );
    }

    /**
     * 获取当前系统同日期
     *
     * @return yyyy-MM-dd
     */
    public static String getCurrentDate() {
        DateTime dateTime = DateTime.now();
        return dateTime.toString( DATE_PATTERN );
    }

    /**
     * 获取当前系统时间
     * 默认模板格式yyyy-MM-dd hh:mm:ss
     *
     * @return
     */
    public static String getCurrentDateTime() {
        DateTime dateTime = DateTime.now();
        return dateTime.toString( DATETIME_PATTERN );
    }

    /**
     * 获取指定格式的日期
     *
     * @param pattern
     * @return
     */
    public static String getCurrentDateTime(String pattern) {
        DateTime dateTime = DateTime.now();
        return dateTime.toString( pattern );
    }

    /**
     * 把字串日期转化成为Date对象
     *
     * @param dateStr
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static Date formatDate(String dateStr) {
        DateTime dateTime = DateTime.parse( dateStr, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        return dateTime.toDate();
    }

    /**
     * 将字符串日期转为Date对象
     *
     * @param dateStr
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date formatDate(String dateStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern( pattern );
        DateTime fromDate = DateTime.parse( dateStr, formatter );
        return fromDate.toDate();
    }

    /**
     * 将字符串日期转为Date对象
     *
     * @param dateStr
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String formatDateToPattern(String dateStr, String pattern) {
        Date date = formatDate( dateStr, pattern );
        DateTime dateTime = new DateTime( date );
        return dateTime.toString( pattern );
    }

    /**
     * 将日期时间转换为日期
     *
     * @param dateTimeStr yyyy-MM-dd
     * @return yyyy-MM-dd
     * @throws ParseException
     */
    public static String formatDateTimeToDate(String dateTimeStr) {
        return formatDateToPattern( dateTimeStr, DATE_PATTERN );
    }

    /**
     * 将日期时间转换为日期
     *
     * @param dateTimeStr yyyy-MM-dd HH:mm:ss
     * @return yyyy-MM-dd
     * @throws ParseException
     */
    public static String formatDateTimeToDateYmd(String dateTimeStr) {
        return formatDateToPattern( dateTimeStr, DATETIME_PATTERN );
    }

    /**
     * 将日期转为日期字符串
     *
     * @param date
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String formatDateToStr(Date date) {
        DateTime dateTime = new DateTime( date );
        return dateTime.toString( DATETIME_PATTERN );
    }

    /**
     * 将日期转换为执行类型的字符串日期
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDateToStr(Date date, String pattern) {
        DateTime dateTime = new DateTime( date );
        return dateTime.toString( pattern );
    }

    /**
     * 指定日期是否在当前日期之后
     *
     * @param dateStr 2019-05-21
     *                2019-05-20 和 2019-05-21 比较返回false
     * @return false
     */
    public static boolean dateIsAfterCuttrntDate(String dateStr) {
        DateTime d1 = DateTime.parse( dateStr, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        DateTime d2 = DateTime.now();
        return d1.isAfter( d2 );
    }

    /**
     * 指定日期是否在当前日期之前
     *
     * @param dateStr 2019-05-20
     *                2019-05-20 和 2019-05-21 比较返回true
     * @return true
     */
    public static boolean dateIsBeforeCuttrntDate(String dateStr) {
        DateTime d1 = DateTime.parse( dateStr, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        DateTime d2 = DateTime.now();
        return d1.isBefore( d2 );
    }

    /**
     * 判断指定日期是否再某个时间范围之内
     *
     * @param day1 开始日期
     * @param day2 结束日期
     * @param day3 指定日期
     * @return
     */
    public static boolean dataIsBetween(String day1, String day2, String day3) {
        DateTime d1 = DateTime.parse( day1, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        DateTime d2 = DateTime.parse( day2, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        DateTime d3 = DateTime.parse( day3, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        return d1.isBefore( d3 ) && d2.isAfter( d3 );
    }

    /**
     * 给指定日期加上指定的天数
     *
     * @param dateTime
     * @param days
     * @return
     * @throws ParseException
     */
    public static String dateTimePlusDays(String dateTime, int days) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat( DATETIME_PATTERN );
            Date date = dateFormat.parse( dateTime );
            long time = date.getTime();
            days = days * 24 * 60 * 60 * 1000;
            time += days;
            new Date( time );
            return dateFormat.format( new Date( time ) );
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateTime;
    }

    /**
     * 给指定时间 加上指定 分钟
     *
     * @param minutes
     * @return
     */
    public static String currentDateTimePlusMinutes(int minutes) {
        return DateTime.now().plusMinutes( minutes ).toString( DATETIME_PATTERN );
    }

    /**
     * 判断指定日期是否和当前系统日期相等
     *
     * @param dateStr
     * @return
     */
    public static boolean dateIsEqualCuttrntDate(String dateStr) {
        return dateIsEqual( dateStr, getCurrentDate() );
    }

    /**
     * 判断两个指定的日期是否相等
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean dateIsEqual(String date1, String date2) {
        DateTime d1 = new DateTime( date1 );
        DateTime d2 = new DateTime( date2 );
        return d1.isEqual( d2 );
    }

    /**
     * 获取当前日期的昨天的日期
     *
     * @return 返回格式yyyy-MM-dd HH:mm:ss
     */
    public static String getYesterday() {
        DateTime dt = new DateTime();
        DateTime yesterday = dt.minusDays( 1 );
        return yesterday.toString( DATETIME_PATTERN );
    }

    /**
     * 获取当前日期的昨天的日期
     *
     * @return 返回格式yyyy-MM-dd
     */
    public static String getYesterdayDate() {
        DateTime dt = new DateTime();
        DateTime yesterday = dt.minusDays( 1 );
        return yesterday.toString( DATE_PATTERN );
    }

    /**
     * 获取当前日期的明天的日期
     *
     * @return 返回格式yyyy-MM-dd HH:mm:ss
     */
    public static String getTomorrowDay() {
        DateTime dt = new DateTime();
        DateTime yesterday = dt.plusDays( 1 );
        return yesterday.toString( DATETIME_PATTERN );
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param day1 yyyy-MM-dd HH:mm:ss
     * @param day2 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static int dayTimesOf2Day(String day1, String day2) {
        DateTime begin = DateTime.parse( day1, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        DateTime end = DateTime.parse( day2, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        Period p = new Period( begin, end, PeriodType.days() );
        return p.getDays();
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param day1 yyyy-MM-dd
     * @param day2 yyyy-MM-dd
     * @return
     */
    public static int daysOf2Day(String day1, String day2) {
        DateTime begin = DateTime.parse( day1, DateTimeFormat.forPattern( DATE_PATTERN ) );
        DateTime end = DateTime.parse( day2, DateTimeFormat.forPattern( DATE_PATTERN ) );
        Period p = new Period( begin, end, PeriodType.days() );
        return p.getDays();
    }

    /**
     * 计算两个日期之间的毫秒数
     *
     * @param day1 yyyy-MM-dd HH:mm:ss
     * @param day2 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static long get2DaysMillis(String day1, String day2) {
        DateTime begin = DateTime.parse( day1, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        ;
        DateTime end = DateTime.parse( day2, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        ;
        Duration d = new Duration( begin, end );
        return d.getMillis();
    }

    /**
     * 计算两个日期之间的秒数
     *
     * @param day1 yyyy-MM-dd HH:mm:ss
     * @param day2 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static long get2DaysSeconds(String day1, String day2) {
        DateTime begin = DateTime.parse( day1, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        ;
        DateTime end = DateTime.parse( day2, DateTimeFormat.forPattern( DATETIME_PATTERN ) );
        ;
        Duration d = new Duration( begin, end );
        return d.getStandardSeconds();
    }

    /**
     * 计算两个日期之间的毫秒数
     *
     * @param day1 yyyy-MM-dd
     * @param day2 yyyy-MM-dd
     * @return
     */
    public static long get2DayTimesMillis(String day1, String day2) {
        DateTime begin = DateTime.parse( day1, DateTimeFormat.forPattern( DATE_PATTERN ) );
        ;
        DateTime end = DateTime.parse( day2, DateTimeFormat.forPattern( DATE_PATTERN ) );
        ;
        Duration d = new Duration( begin, end );
        return d.getMillis();
    }

    /**
     * 获取系统日期-年
     *
     * @return 当前年
     */
    public static int getYear() {
        DateTime dt = new DateTime();
        return dt.getYear();
    }

    /**
     * 获取系统日期-月
     *
     * @return 当前月
     */
    public static int getMonthOfYear() {
        DateTime dt = new DateTime();
        return dt.getMonthOfYear();
    }

    /**
     * 获取系统日期-日
     *
     * @return 当前日
     */
    public static int getDayOfMonth() {
        DateTime dt = new DateTime();
        return dt.getDayOfMonth();
    }

    /**
     * 获取系统时间---点
     *
     * @return 当前时间点 12点
     */
    public static int getHourOfDay() {
        DateTime dt = new DateTime();
        return dt.getHourOfDay();
    }

    /**
     * 获取系统时间---分
     *
     * @return 当前时间点 32分
     */
    public static int getMinuteOfHour() {
        DateTime dt = new DateTime();
        return dt.getMinuteOfHour();
    }

    /**
     * 获取系统时间---秒
     *
     * @return 当前时间点 32秒
     */
    public static int getSecondOfMinute() {
        DateTime dt = new DateTime();
        return dt.getSecondOfMinute();
    }

    /**
     * 获取系统时间---毫秒
     *
     * @return 当前时间点 335毫秒
     */
    public static int getMillisOfSecond() {
        DateTime dt = new DateTime();
        return dt.getMillisOfSecond();
    }

    /**
     * 获取当前月的第一天日期
     *
     * @return 90天后那周的周一
     * DateTime firstday = dt.plusDays(90).dayOfWeek().withMinimumValue();
     */
    public static String getFirstdayOfMonth() {
        DateTime dt = new DateTime();
        DateTime lastday = dt.dayOfMonth().withMinimumValue();
        return lastday.toString( DATE_PATTERN );
    }

    /**
     * 获取当前月的最后一天日期
     *
     * @return
     */
    public static String getLastdayOfMonth() {
        DateTime dt = new DateTime();
        DateTime lastday = dt.dayOfMonth().withMaximumValue();
        return lastday.toString( DATE_PATTERN );
    }

    /**
     * 根据当前系统日期获取当天是星期几
     *
     * @return
     */
    public static String getDayOfWeek() {
        return getDayOfWeek( getCurrentDate() );
    }

    /**
     * 获取指定日期的星期
     *
     * @param dateStr 2019-05-01
     * @return
     */
    public static String getDayOfWeek(String dateStr) {
        String currentWeek = "";
        DateTime dt = new DateTime( dateStr );
        switch (dt.getDayOfWeek()) {
            case DateTimeConstants.SUNDAY:
                currentWeek = "星期日";
                break;
            case DateTimeConstants.MONDAY:
                currentWeek = "星期一";
                break;
            case DateTimeConstants.TUESDAY:
                currentWeek = "星期二";
                break;
            case DateTimeConstants.WEDNESDAY:
                currentWeek = "星期三";
                break;
            case DateTimeConstants.THURSDAY:
                currentWeek = "星期四";
                break;
            case DateTimeConstants.FRIDAY:
                currentWeek = "星期五";
                break;
            case DateTimeConstants.SATURDAY:
                currentWeek = "星期六";
                break;
            default:
                break;
        }
        return currentWeek;
    }

    /**
     * 获取当前时间的上一个月的 此时的时间
     *
     * @return
     */
    public static int getBeforeCurrentMonth() {
        DateTime dt = new DateTime();
        DateTime beforeMonth = dt.minusMonths( 1 );
        return beforeMonth.getMonthOfYear();
    }

    /**
     * 获取当前时间之后多少秒的时间 返回 ISO 8601 UTC 类型
     *
     * @return
     */
    public static String getAfterCurrentTimeISO(int minutes) {
        LocalDateTime ldt = new LocalDateTime();
        ldt.plusMinutes( minutes );
        DateTime nowUTC = ldt.toDateTime( DateTimeZone.UTC );
        return nowUTC.toString();
    }


    public static void main(String[] args) throws ParseException {
//		System.out.println(getCurrentDateTime());
//		System.out.println(getDayOfWeek("2019-05-21"));
//		System.out.println(dateIsAfterCuttrntDate("2019-05-20"));
//		System.out.println(dateIsBeforeCuttrntDate("2020-02-05 13:50:40"));
//		System.out.println(getMillisOfSecond());
//		System.out.println(getLastdayOfMonth());
//		System.out.println(getFirstdayOfMonth());
//		System.out.println(getBeforeCurrentMonth());
//		System.out.println(formatDateToStr(new Date()));
//		System.out.println(DateTime.now());
//		System.out.println(dataIsBetween("2020-02-05 13:50:40","2020-02-07 13:50:40","2020-02-06 13:50:40"));
        System.out.println( dateTimePlusDays( "2020-02-05 13:50:40", 3 ) );
        System.out.println( currentDateTimePlusMinutes( 10 ) );
//		System.out.println(formatDateTimeToDate("2020-02-05 13:50:40"));
//      System.out.println(formatDateToPattern("2020-02-05",DATETIME_PATTERN));
//      System.out.println(formatDate("2020-02-05 13:50:40",DATE_PATTERN));
//		System.out.println(daysOf2Day("2020-02-05","2020-02-06"));
//		System.out.println(dayTimesOf2Day("2020-02-05 13:50:40","2020-02-06 19:50:50"));
//		System.out.println(get2DaysMillis("2020-02-05 13:50:40","2020-02-05 19:50:50"));
//		System.out.println(get2DayTimesMillis("2020-02-05","2020-02-06"));
//		System.out.println(formatDate("2020-02-05"));
        System.out.println( formatDate( "2020-02-05 13:50:40", DATETIME_PATTERN ) );
//		System.out.println(formatDate("2020-02-05",DATE_PATTERN));
        System.out.println( String.format( "%10s", "123459" ) );
    }
}